#include <soar.h>

#define SERVER_PORT         59999
#define	THRD_NUM			10
#define	TRANSFER_SIZE		(64)

typedef struct
{
    unsigned int thrd_id;
	int thrd_index;
} thrd_ctl_t;

struct sockd_addr peer_addr;

void *thrd_func(thrd_ctl_t *thrd_ctl)
{
    int res;
    int sock;
    char *msg_in=NULL;
    int msg_in_size;
    char *msg_out=NULL;
    int msg_out_size;
    char *p;
    int count;
    int loop_qt;
    int timeout_ms=-1;
    
    if((sock=sockd_create()) == INVALID_SOCKET)
    {
        printf("socket create failed\n");
        goto ERROR_OUT;
    }

	ALLOC_MULTI(msg_in, char, SOCKD_MSG_SIZE, ERROR_OUT);
	ALLOC_MULTI(msg_out, char, SOCKD_MSG_SIZE, ERROR_OUT);

#ifdef _MY_MULTI
    memset(msg_in, CHAR0, TRANSFER_SIZE);
	msg_in[TRANSFER_SIZE]=ZERO;

    count=0;
    if(THRD_NUM > 1)
        loop_qt=100000;
    else
        loop_qt=1000000;
    while(count < loop_qt)
    {
        msg_in_size=TRANSFER_SIZE;
#else
    while(fgets(msg_in, SOCKD_MSG_SIZE, stdin)!=NULL)
    {
        if((p=strchr(msg_in, RTN))) *p=ZERO;
        msg_in_size=strlen(msg_in);
        printf("msg_in(%d): %s\n", msg_in_size, msg_in);
#endif
        if((res=sockd_sendto(sock, &peer_addr,
                        (unsigned char *)msg_in, &msg_in_size,
                        &timeout_ms)))
        {
            if(res == RET_ERR_TIMEOUT)
                printf("socket write time out\n");
            else
                printf("socket write fail, res:%d\n", res);
            goto ERROR_OUT;
        }
        if((res=sockd_recvfrom(sock, NULL,
                        (unsigned char *)msg_out, &msg_out_size,
                        &timeout_ms)))
        {
            if(res == RET_ERR_TIMEOUT)
                printf("socket read time out\n");
            else
                printf("socket read fail, res:%d\n", res);
            goto ERROR_OUT;
        }
#ifdef _MY_MULTI
        count++;
        if(count % 10000 == 0)
            printf("thread(%d): %d finished\n",
				thrd_ctl->thrd_index, count);
#else
        msg_out[msg_out_size]=ZERO;
        printf("msg_out(%d):%s\n", msg_out_size, msg_out);
#endif
    }

	FREE(msg_in);
	FREE(msg_out);
    sock_close(sock);    
    printf("Succeed\n");
    return(NULL);

ERROR_OUT:
	FREE(msg_in);
	FREE(msg_out);
    sock_close(sock);    
    printf("Fail\n");
    return(NULL);
}

int main(int argc, char *argv[])
{
    char peer[LONG_FILE_NM_SIZE+1];
#ifdef _MY_MULTI
	thrd_ctl_t a_thrd_ctl[THRD_NUM];
	int thrd_index;
#endif

    if(argc == 1)
        sprintf(peer, "localhost:%d", SERVER_PORT);
    else
        sprintf(peer, "%s:%d", argv[1], SERVER_PORT);
    sockd_addr_convert(peer, &peer_addr);

#ifdef _MY_MULTI
	for(thrd_index=0; thrd_index<THRD_NUM; thrd_index++)
	{
		a_thrd_ctl[thrd_index].thrd_index=thrd_index;
		if(thrd_create((THRD_FUNC_T)thrd_func,
                    (void *)&a_thrd_ctl[thrd_index], 0,
                    &a_thrd_ctl[thrd_index].thrd_id))
        {
            printf("thrd create fail\n");
            return(-1);
        }
        //sleep(1);
    }
	for(thrd_index=0; thrd_index<THRD_NUM; thrd_index++)
        thrd_join(a_thrd_ctl[thrd_index].thrd_id);
#else
    thrd_func(NULL);
#endif

    return(0);
}
